home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / chromakey.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  5.6 KB  |  263 lines

  1. #include <assert.h>
  2. #include <math.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <GL/glut.h>
  6. #include "texture.h"
  7.  
  8. static char defaultFile0[] = "data/blurredsgi.bw";
  9. static char defaultFile1[] = "data/mandrill256.rgb";
  10. static char defaultFile2[] = "data/brick.rgb";
  11. GLuint *img0, *img1, *img2;
  12. GLsizei w, h;
  13. GLsizei w0, w1, w2, h0, h1, h2;
  14. GLint comp;
  15. GLfloat key[3] = {0, 0, 0};
  16.  
  17. #define RW 0.3086
  18. #define GW 0.6094
  19. #define BW 0.0820
  20.  
  21. void init(void)
  22. {
  23. }
  24.  
  25. GLuint *load_img(const char *fname, GLsizei *imgW, GLsizei *imgH)
  26. {
  27.   GLuint *img;
  28.  
  29.   img = read_texture(fname, imgW, imgH, &comp);
  30.   if (!img) {
  31.     fprintf(stderr, "Could not open %s\n", fname);
  32.     exit(1);
  33.   }
  34.  
  35.   return img;
  36. }
  37.  
  38. GLuint *
  39. resize_img(GLuint *img, GLsizei curW, GLsizei curH)
  40. {
  41.  
  42.   glPixelZoom((float)w / (float)curW, (float)h / (float)curH);
  43.   glRasterPos2i(0, 0);
  44.   glDrawPixels(curW, curH, GL_RGBA, GL_UNSIGNED_BYTE, img);
  45.   free(img);
  46.   img = (GLuint *)malloc(w * h * sizeof(GLuint));
  47.   if (!img) {
  48.     fprintf(stderr, "Malloc of %d bytes failed.\n", 
  49.         curW * curH * sizeof(GLuint));
  50.     exit(1);
  51.   }
  52.   glPixelZoom(1, 1);
  53.   glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img);
  54.  
  55.   return img;
  56. }
  57.  
  58. void reshape(GLsizei winW, GLsizei winH) 
  59. {
  60.     glViewport(0, 0, 2*w, 2*h);
  61.     glLoadIdentity();
  62.     glOrtho(0, 2*w, 0, 2*h, 0, 5);
  63. }
  64.  
  65. void compute_matte(void)
  66. {
  67.   glClear(GL_ACCUM_BUFFER_BIT);
  68.  
  69.   /* draw rectangle in (key color + 1) / 2 */
  70.   glBegin(GL_QUADS);
  71.   glColor3f(key[0], key[1], key[2]);
  72.   glVertex2f(0, 0);
  73.   glVertex2f(w, 0);
  74.   glVertex2f(w, h);
  75.   glVertex2f(0, h);
  76.   glEnd();
  77.   glFlush();
  78.  
  79.   /* negate & accumulate  */
  80.   glAccum(GL_LOAD, -1);
  81.  
  82.   /* compute & return (image - key) */
  83.   glRasterPos2f(0, 0);
  84.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0);
  85.   glAccum(GL_ACCUM, 1);
  86.   glAccum(GL_RETURN, 1);
  87.  
  88.   /* move to right hand side of window */
  89.   glRasterPos2f(w, 0);
  90.   glCopyPixels(0, 0, w, h, GL_COLOR);
  91.  
  92.   /* compute & return (key - image) */
  93.   glEnable(GL_SCISSOR_TEST);
  94.   glScissor(0, 0, w, h);
  95.   glAccum(GL_MULT, -1);
  96.   glAccum(GL_RETURN, 1);
  97.   glScissor(0, 0, 2*w, h);
  98.   glDisable(GL_SCISSOR_TEST);
  99.  
  100.   /* assemble to get fabs(key - image) */
  101.   glBlendFunc(GL_ONE, GL_ONE);
  102.   glEnable(GL_BLEND);
  103.   glRasterPos2i(0, 0);
  104.   glCopyPixels(w, 0, w, h, GL_COLOR);
  105.   glDisable(GL_BLEND);
  106.  
  107.   /* assemble into alpha channel */
  108.   {
  109.     GLfloat mat[] = {
  110.       RW, RW, RW, RW,
  111.       GW, GW, GW, GW,
  112.       BW, BW, BW, BW,
  113.       0, 0, 0, 0,
  114.     };
  115.     glMatrixMode(GL_COLOR);
  116.     glLoadMatrixf(mat);
  117.  
  118.     glRasterPos2i(w, 0);
  119.     glCopyPixels(0, 0, w, h, GL_COLOR);
  120.     glLoadIdentity();
  121.     glMatrixMode(GL_MODELVIEW);
  122.   }
  123.  
  124.   /* copy matte to right */
  125.   glRasterPos2i(0, 0);
  126.   glCopyPixels(w, 0, w, h, GL_COLOR);
  127.  
  128.   /* draw the third image */
  129.   glColorMask(1, 1, 1, 0);
  130.   glRasterPos2i(w, 0);
  131.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img2);
  132.   glColorMask(1, 1, 1, 1);
  133.  
  134.   glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
  135.   glEnable(GL_BLEND);
  136.   glRasterPos2i(w, 0);
  137.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img1);
  138.  
  139.   /* this is for matte display... */
  140.   glColor3f(1, 1, 1);
  141.   glBegin(GL_QUADS);
  142.   glVertex2f(0, 0);
  143.   glVertex2f(w, 0);
  144.   glVertex2f(w, h);
  145.   glVertex2f(0, h);
  146.   glEnd();
  147.  
  148.   glDisable(GL_BLEND);
  149. }
  150.  
  151. void draw(void)
  152. {
  153.   GLenum err;
  154.   static int first = 1;
  155.   
  156.   if (first) {
  157.     printf("Scaling images to %d by %d\n", w, h);
  158.  
  159.  
  160.     if (w0 != w || h0 != h) {
  161.       img0 = resize_img(img0, w0, h0);
  162.  
  163.     }
  164.     if (w1 != w || h1 != h) {
  165.       img1 = resize_img(img1, w1, h1);
  166.     }
  167.     if (w2 != w || h2 != h) {
  168.       img2 = resize_img(img2, w2, h2);
  169.     }
  170.     first = 0;
  171.   }
  172.   
  173.   
  174.   glClear(GL_COLOR_BUFFER_BIT);
  175.   compute_matte();
  176.   
  177.   glRasterPos2i(w/2, h);
  178.   glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, img0);
  179.  
  180.   err = glGetError();
  181.   if (err != GL_NO_ERROR) printf("Error:  %s\n", gluErrorString(err));
  182. }
  183.  
  184. /* ARGSUSED */
  185. void button(int button, int state, int xpos, int ypos)
  186. {
  187.   if (state != GLUT_UP) return;
  188.  
  189.   ypos = 2*h - ypos;
  190.   glReadPixels(xpos, ypos, 1, 1, GL_RGB, GL_FLOAT, key);
  191.   printf("Key is (%f %f %f)\n", key[0], key[1], key[2]);
  192.   draw();
  193. }
  194.  
  195. /* ARGSUSED1 */
  196. void keyPress(unsigned char whichKey, int x, int y)
  197. {
  198.   if (whichKey == 27) exit(0);
  199. }
  200.  
  201. void show_usage(void) 
  202. {
  203.   fprintf(stderr, "Usage:\n");
  204.   fprintf(stderr, "chromakey mattefile file0 file1 [matteR matteG matteB]\n");
  205.   fprintf(stderr, "chromakey mattefileAndfile0 file1 [matteR matteG matteB]\n");
  206. }
  207.  
  208. main(int argc, char *argv[])
  209. {
  210.   char *fileName0 = defaultFile0, *fileName1 = defaultFile1, 
  211.   *fileName2 = defaultFile2;
  212.   
  213.   glutInit(&argc, argv);
  214.   if (argc > 1) {
  215.     fileName0 = fileName1 = argv[1];
  216.   }
  217.   if (argc > 2) {
  218.     fileName2 = argv[2];
  219.   }
  220.   if (argc > 3) {
  221.     fileName1 = fileName2;
  222.     fileName2 = argv[3];
  223.   }
  224.   if (argc > 4) {
  225.     if (argc == 6 || argc == 7) {
  226.       key[0] = atof(argv[argc-3]);
  227.       key[1] = atof(argv[argc-2]);
  228.       key[2] = atof(argv[argc-1]);
  229.     } else {
  230.       show_usage();
  231.       exit(1);
  232.     }
  233.   }
  234.   
  235.   printf("Matte file is %s\n", fileName0);
  236.   printf("Image file 1 is %s\n", fileName1);
  237.   printf("Image file 2 is %s\n", fileName2);
  238.   printf("Key is (%f %f %f)\n", key[0], key[1], key[2]);
  239.   img0 = load_img(fileName0, &w0, &h0);
  240.   img1 = load_img(fileName1, &w1, &h1);
  241.   img2 = load_img(fileName2, &w2, &h2);
  242.   
  243. #define MAX(a, b) ((a) > (b) ? (a) : (b))
  244.   w = MAX(MAX(w0, w1), w2);
  245.   h = MAX(MAX(h0, h1), h2);
  246.   
  247.   glutInitWindowSize(2*w, 2*h);
  248.   glutInitWindowPosition(0, 0);
  249.   glutInitDisplayMode(GLUT_RGBA | GLUT_ACCUM | GLUT_ALPHA);
  250.   glutCreateWindow(argv[0]);
  251.   glutDisplayFunc(draw);
  252.   glutKeyboardFunc(keyPress);
  253.   glutReshapeFunc(reshape);
  254.   glutMouseFunc(button);
  255.  
  256.  
  257.   init();
  258.   
  259.   reshape(w, h);
  260.   glutMainLoop();
  261.   return 0;
  262. }
  263.